package net.simflow.swf.analyzer.exec.stats.opt;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import net.simflow.swf.analyzer.exec.data.TaskExecResult;
import net.simflow.swf.analyzer.network.data.Flow;

public class FlowCountAnalyzer {

	private static FlowCountAnalyzer instance = new FlowCountAnalyzer();

	private FlowCountAnalyzer() {
	}

	public static FlowCountAnalyzer getInstance() {
		return instance;
	}

	public HashMap<Flow, ArrayList<TaskExecResult>> analyzeTotalTask(
			TreeMap<Integer, TaskExecResult> taskExecMap) {
		HashMap<Flow, ArrayList<TaskExecResult>> map = new HashMap<Flow, ArrayList<TaskExecResult>>();

		if (taskExecMap == null) {
			return map;
		}

		taskExecMap.comparator();

		for (TaskExecResult res : taskExecMap.values()) {
			ArrayList<TaskExecResult> a = map.get(res.getFlow());
			if (a == null) {
				a = new ArrayList<TaskExecResult>();
				map.put(res.getFlow(), a);
			}
			a.add(res);
		}

		return map;
	}

	public HashMap<Flow, ArrayList<TaskExecResult>> analyzeExecTask(
			TreeMap<Integer, TaskExecResult> taskExecMap) {
		HashMap<Flow, ArrayList<TaskExecResult>> map = new HashMap<Flow, ArrayList<TaskExecResult>>();

		if (taskExecMap == null) {
			return map;
		}

		taskExecMap.comparator();

		for (TaskExecResult res : taskExecMap.values()) {
			if (res.getEndTime() != -1) {
				ArrayList<TaskExecResult> a = map.get(res.getFlow());
				if (a == null) {
					a = new ArrayList<TaskExecResult>();
					map.put(res.getFlow(), a);
				}
				a.add(res);
			}
		}

		return map;
	}

	public HashMap<Flow, ArrayList<TaskExecResult>> analyzeUnfinishedTask(
			TreeMap<Integer, TaskExecResult> taskExecMap) {
		HashMap<Flow, ArrayList<TaskExecResult>> map = new HashMap<Flow, ArrayList<TaskExecResult>>();

		if (taskExecMap == null) {
			return map;
		}

		taskExecMap.comparator();

		for (TaskExecResult res : taskExecMap.values()) {
			if (res.getEndTime() == -1) {
				ArrayList<TaskExecResult> a = map.get(res.getFlow());
				if (a == null) {
					a = new ArrayList<TaskExecResult>();
					map.put(res.getFlow(), a);
				}
				a.add(res);
			}
		}

		return map;
	}

	public TreeMap<Integer, ArrayList<Flow>> analyzeDistribution(
			Map<Flow, ArrayList<TaskExecResult>> flowCountmap) {
		TreeMap<Integer, ArrayList<Flow>> map = new TreeMap<Integer, ArrayList<Flow>>();

		if (flowCountmap == null) {
			return map;
		}

		for (Entry<Flow, ArrayList<TaskExecResult>> en : flowCountmap
				.entrySet()) {
			if (en.getValue() == null) {
				continue;
			}
			Flow flow = en.getKey();
			int count = en.getValue().size();
			ArrayList<Flow> a = map.get(count);
			if (a == null) {
				a = new ArrayList<Flow>();
				map.put(count, a);
			}
			a.add(flow);
		}
		map.comparator();

		return map;
	}
}
